package com.example.java_chatroom_redis_rabbitmq.component;

import com.example.java_chatroom_redis_rabbitmq.service.MessageService;
import com.example.java_chatroom_redis_rabbitmq.service.NewFriendService;
import com.example.java_chatroom_redis_rabbitmq.service.SessionService;
import com.example.java_chatroom_redis_rabbitmq.service.TodoService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class RabbitMessageQueueListener implements MessageListener {
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SessionService sessionService;

    @Autowired
    private WebSocketSessionManager webSocketSessionManager;

    @Autowired
    private TodoService todoService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private NewFriendService newFriendService;
    @Transactional
    @Override
    public void onMessage(Message message) {
        String jsonString = new String(message.getBody(), StandardCharsets.UTF_8);
        com.example.java_chatroom_redis_rabbitmq.model.Message message1 = null;
        try {
            //将Message转换为我们定义的Message对象
            message1 = objectMapper.readValue(jsonString, com.example.java_chatroom_redis_rabbitmq.model.Message.class);
        } catch (JsonProcessingException e) {
            log.error("消息转换为Message对象失败!");
        }
        if (message1 == null) {
            log.error("message为空");
        }
        if ("message".equals(message1.getType())) {
            log.info(message1.getContent());
            //将消息增加到数据库中
            Integer ret = messageService.addMessage(message1);
            if (ret <= 0) {
                log.error("消息增加失败!【message1】:" + message);
            }
            ret = sessionService.updateSession(message1.getSessionId(), message1.getContent());
            Integer sessionId = message1.getSessionId();
            //根据sessionId获取该会话中的用户，然后根据用户的在线状态选择消息的转发
            List<Integer> userIds = sessionService.getUserIdsBySessionId(sessionId, message1.getFromId());
            for (Integer userId : userIds) {
                WebSocketSession session = webSocketSessionManager.getSessionByUserId(userId);
                if (session != null) {
                    //session不为null表示该用户处于在线状态
                    try {
                        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message1)));
                    } catch (IOException e) {
                        log.error("消息发送失败,【message】:" + message1);
                    }
                }
                ret = todoService.addTodoCount(userId,sessionId);
                if (ret < 0) {
                    log.error("增加待处理消息失败!");
                }else if (ret == 0) {
                    todoService.createTodoMessage(userId,sessionId);
                }
            }
        }else if ("friend".equals(message1.getType())) {
            Integer ret = newFriendService.addNewFriend(message1);
            if (ret <= 0) log.error("增加新朋友失败!");
            WebSocketSession session = webSocketSessionManager.getSessionByUserId(message1.getToId());
            if (session != null) {
                try {
                    session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message1)));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
